package com.sheng.project.demo.utils;

import org.springframework.util.Base64Utils;

import javax.crypto.Cipher;
import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import java.nio.charset.StandardCharsets;

/**
 * AES对称算法
 * 加解密
 */
public class AESUtilV2 {

    private static final String ALGORITHM_AES = "AES";
    private static final int ALGORITHM_AES_KEY_SIZE = 128;
    private static final String TRANSFORMATION_AES = "AES/CBC/PKCS5Padding";

    /**
     * 加密
     *
     * @param plainText 明文
     * @param key       密钥
     * @return 密文
     */
    public String encrypt(String plainText, String key) {
        try {
            SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), ALGORITHM_AES);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes(StandardCharsets.UTF_8), 0, 16);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION_AES);// 创建密码器
            cipher.init(Cipher.ENCRYPT_MODE, sKey, iv);// 初始化
            byte[] cipherTextData = cipher.doFinal(plainText.replaceAll("\r|\n", "").getBytes(StandardCharsets.UTF_8));
            return Base64Utils.encodeToString(cipherTextData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new IllegalArgumentException("AES对称性加密失败。");
    }

    /**
     * 加密
     *
     * @param plainText 明文
     * @param key       密钥
     * @param ivParam   向量
     * @return 密文
     */
    public String encrypt(String plainText, String key, String ivParam) {
        try {
            SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), ALGORITHM_AES);
            IvParameterSpec iv = new IvParameterSpec(ivParam.getBytes(StandardCharsets.UTF_8), 0, 16);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION_AES);// 创建密码器
            cipher.init(Cipher.ENCRYPT_MODE, sKey, iv);// 初始化
            byte[] cipherTextData = cipher.doFinal(plainText.replaceAll("\r|\n", "").getBytes(StandardCharsets.UTF_8));
            return Base64Utils.encodeToString(cipherTextData);
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new IllegalArgumentException("AES对称性加密失败。");
    }

    /**
     * 解密
     *
     * @param cipherText 密文
     * @param key        密钥
     * @return 明文
     */
    public String decrypt(String cipherText, String key) {
        try {
            SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), ALGORITHM_AES);
            IvParameterSpec iv = new IvParameterSpec(key.getBytes(StandardCharsets.UTF_8), 0, 16);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION_AES);// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, sKey, iv);// 初始化
            byte[] cipherTextData = Base64Utils.decodeFromString(cipherText.replaceAll("\r|\n", ""));
            byte[] plainTextData = cipher.doFinal(cipherTextData);
            return new String(plainTextData, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new IllegalArgumentException("AES对称性解密失败。");
    }

    /**
     * 解密
     *
     * @param cipherText 密文
     * @param key        密钥
     * @param ivParam    向量
     * @return 明文
     */
    public String decrypt(String cipherText, String key, String ivParam) {
        try {
            SecretKeySpec sKey = new SecretKeySpec(key.getBytes(), ALGORITHM_AES);
            IvParameterSpec iv = new IvParameterSpec(ivParam.getBytes(StandardCharsets.UTF_8), 0, 16);
            Cipher cipher = Cipher.getInstance(TRANSFORMATION_AES);// 创建密码器
            cipher.init(Cipher.DECRYPT_MODE, sKey, iv);// 初始化
            byte[] cipherTextData = Base64Utils.decodeFromString(cipherText.replaceAll("\r|\n", ""));
            byte[] plainTextData = cipher.doFinal(cipherTextData);
            return new String(plainTextData, StandardCharsets.UTF_8);
        } catch (Exception e) {
            e.printStackTrace();
        }
        throw new IllegalArgumentException("AES对称性解密失败。");
    }

}
